package com.tuni.birthdaymoney.web.controller;

import java.security.Principal;
import java.util.Calendar;
import java.util.Map;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.tuni.birthdaymoney.persistence.entity.Operation;
import com.tuni.birthdaymoney.persistence.entity.Person;
import com.tuni.birthdaymoney.persistence.entity.QPerson;
import com.tuni.birthdaymoney.persistence.entity.User;
import com.tuni.birthdaymoney.service.OperationService;
import com.tuni.birthdaymoney.service.PersonService;
import com.tuni.birthdaymoney.service.UserService;
import com.tuni.birthdaymoney.service.util.email.BirthdayUtils;
import com.tuni.birthdaymoney.web.model.DonationsPage;
import com.tuni.birthdaymoney.web.model.MasterPage;

@Controller
public class DonationsController {

    @Autowired
    private OperationService operationService;

    @Autowired
    private PersonService personService;

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/donations/{receiptorId}", method = RequestMethod.GET)
    public String donations(Principal principal, @PathVariable("receiptorId") Integer receiptorId, Map<String, Object> donationsPageMap) {
        return showDonationsPage(principal, receiptorId, donationsPageMap, new DonationsPage());
    }

    @RequestMapping(value = "/donations/{receiptorId}/add", method = RequestMethod.POST)
    public String addDonation(@Valid @ModelAttribute("donationsPageModel") DonationsPage donationsPageModel, BindingResult result,
            @PathVariable("receiptorId") Integer receiptorId, Principal principal, Map<String, Object> donationsPageMap) {
        if (!result.hasErrors()) {
            if (donationsPageModel.getOperation().getAmount().doubleValue() < 0) {
                result.rejectValue("operation.amount", "error.user", "Amount should be greater than zero");
                return showDonationsPage(principal, receiptorId, donationsPageMap, donationsPageModel);
            }
            operationService.saveDonation(donationsPageModel.getOperation());
            return String.format("redirect:/donations/%s.html", receiptorId);
        }
        return showDonationsPage(principal, receiptorId, donationsPageMap, donationsPageModel);
    }

    private String showDonationsPage(Principal principal, @PathVariable("receiptorId") Integer receiptorId,
            Map<String, Object> donationsPageMap, DonationsPage donationsPageModel) {
        User hr_user = userService.getUserByEmail(principal.getName());
        Person hr_person = hr_user.getPerson();
        Person receiptor = personService.getById(receiptorId);

        MasterPage masterPageModel = new MasterPage(hr_user, false);
        donationsPageMap.put("masterPageModel", masterPageModel);
        if (receiptor != null && donationsPageModel != null) {
            int year = BirthdayUtils.getNextBirthday(receiptor.getBirthday().toGregorianCalendar(), Calendar.getInstance()).get(
                    Calendar.YEAR);
            donationsPageModel.setAllPeople(personService.findAll(QPerson.person.fired.isFalse()));
            donationsPageModel.setDonators(operationService.getDonators(receiptor, year));
            donationsPageModel.setTotalAmount(operationService.getTotalAmount(receiptor, year));
            if (donationsPageModel.getOperation() == null) {
                donationsPageModel.setOperation(new Operation());
                donationsPageModel.getOperation().setYear(year);
            }
            // refresh foreign key connected entities
            donationsPageModel.getOperation().setReceiptor(receiptor);
            donationsPageModel.getOperation().setHumanResources(hr_person);
            donationsPageMap.put("donationsPageModel", donationsPageModel);
            return "donations";
        } else {
            // TODO: process error here
            return "redirect:/home.html";
        }

    }
}
